<template>
  <div class="event-setting-container">
    <SectionTitle title="权限设置" style="margin-bottom: 12px">
      <span class="title-tip">(设置审批表单流程的权限，可创建多个权限组)</span>
      <div class="options-btn-group">
        <PlainCreateBtn @click="createNewRow">添加</PlainCreateBtn>
        <el-button
          :disabled="!curSelectedRows.length"
          size="small"
          type="danger"
          plain
          class="option-btn"
          @click="handleRowsDel"
        >删除</el-button>
      </div>
    </SectionTitle>
    <el-table
      :data="orders"
      fit
      border
      class="fb-table"
      empty-text="暂无数据"
      header-cell-class-name="dynamic-edit-table-cell"
      @selection-change="onSelectChange">
      <EmptyPlaceholder slot="empty" is-border mode="table" style="padding-bottom: 0; height: 48px" />
      <el-table-column type="selection" fixed="left" align="center" width="50" />
      <el-table-column prop="name" min-width="140">
        <template slot="header" slot-scope="scope">
          <div class="dynamic-table-header">
            <span style="color: #f56c6c;">*</span>
            <span class="label">权限组名</span>
          </div>
        </template>
        <template slot-scope="scope">
          <div :class="{ 'isError': errorCell.includes(`name${scope.row['orderPrivateId']}`) }">
            <el-input
              v-model="scope.row['name']"
              maxlength="12"
              style="font-size: 13px;"
              type="text"
              size="small"
              placeholder="请输入"
              @blur="handleChangeVal(scope.row['name'])"/>
          </div>
        </template>
      </el-table-column>
      <el-table-column prop="isSelectAll" label="设为默认" min-width="80">
        <template slot-scope="scope">
          <div class="flex-center" style="padding-left: 10px">
            <el-switch v-model="scope.row['isSelectAll']" class="fb-switch" @change="handleSelectAll($event, scope.$index)" />
          </div>
        </template>
      </el-table-column>
      <el-table-column prop="members" label="权限所属人员" min-width="160">
        <template slot-scope="scope">
          <div class="members-box" @click="userSelectDialogShow(scope.$index)">
            <el-input v-if="scope.row['isSelectAll']" disabled suffix-icon="el-icon-arrow-down" placeholder="请选择" />
            <span v-else-if="hasMembers(scope.row)" class="member-checked">已选中{{ scope.row['members'].length }}人</span>
            <el-input v-else suffix-icon="el-icon-arrow-down" class="operate-input" placeholder="请选择"/>
          </div>
        </template>
      </el-table-column>
      <el-table-column prop="deptList" label="权限所属部门" min-width="160">
        <template slot-scope="scope">
          <CascaderSelect
            v-model="scope.row['deptList']"
            :disabled="scope.row['isSelectAll']"
            :options="deptTreeList"
            :popper-class="'fixed-dept'"
            class="dept-select-box"
            placeholder="请选择"
            value-name="id"
            label-name="name"
            children="children"
            @changeValue="changeValue($event, scope.row, scope.$index)" />
        </template>
      </el-table-column>
      <el-table-column prop="postList" label="权限所属职位" min-width="200">
        <template slot-scope="scope">
          <selectWithUserLoad
            v-model="scope.row['postList']"
            :disabled="scope.row['isSelectAll']"
            :default-list="scope.row['selectedPostList'] || []"
            :loadmore-method="queryAllPost()"
            multiple
            open-tool-tip
            class="post-selector"
            placeholder="请选择"
            label-name="name"
            filterable
            clearable
          />
        </template>
      </el-table-column>
      <el-table-column prop="roleGroup" label="权限所属角色组" min-width="185">
        <template slot-scope="scope">
          <SelectWithoutHttp
            v-model="scope.row['roleGroup']"
            :disabled="scope.row['isSelectAll']"
            :list-data="roleGroupList"
            label-name="name"
            multiple
            collapse-tags
            clearable />
        </template>
      </el-table-column>
      <el-table-column prop="readPermissions" label="可读权限" min-width="185">
        <template slot-scope="scope">
          <SelectWithoutHttp
            v-model="scope.row['readPermissions']"
            :list-data="readPermissionList"
            label-name="label"
            key-name="value"
            multiple
            collapse-tags
            clearable />
        </template>
      </el-table-column>
      <el-table-column prop="deptScope" label="可读部门数据范围" min-width="160">
        <template slot-scope="scope">
          <CascaderSelect
            v-model="scope.row['deptScope']"
            :options="readDeptTreeList"
            class="dept-select-box"
            placeholder="请选择"
            value-name="id"
            label-name="name"
            children="children" />
        </template>
      </el-table-column>
      <el-table-column prop="operatePermissions" label="操作权限" min-width="185">
        <template slot-scope="scope">
          <SelectWithoutHttp
            v-model="scope.row['operatePermissions']"
            :list-data="operatePermissionList"
            label-name="label"
            key-name="value"
            multiple
            collapse-tags
            clearable />
        </template>
      </el-table-column>
      <el-table-column prop="fieldPermissions" label="不可读组件" min-width="185">
        <template slot-scope="scope">
          <SelectWithoutHttp
            v-model="scope.row['fieldPermissions']"
            :list-data="permissionFields"
            label-name="name"
            key-name="key"
            filterable
            multiple
            collapse-tags
            clearable />
        </template>
      </el-table-column>
      <el-table-column align="left" label="操作" width="100" fixed="right">
        <template slot-scope="scope">
          <div class="flex-center" style="padding: 0 10px;">
            <el-button type="text" @click="handleDelete(scope.row, scope.$index)">
              <span style="font-size:14px; color: red;">删除</span>
            </el-button>
            <div class="border-left" />
            <el-button type="text" @click="handleCopy(scope.row)">
              <span style="font-size:14px;">复制</span>
            </el-button>
          </div>
        </template>
      </el-table-column>
    </el-table>
    <DiversAuditorDialog ref="auditorDialog" @userSelect="userSelectedCallback" />
  </div>
</template>

<script>
import SectionTitle from '@/components/Title';
import SelectWithoutHttp from '@/components/Common/selectWithoutHttp';
import selectWithUserLoad from '@/components/Common/selectWithUserLoad';
import DiversAuditorDialog from '@/components/Common/auditProcess/module/diversAuditorDialog';
import CascaderSelect from '@/components/Tool/module/cascaderSelect';
import EmptyPlaceholder from '@/components/Common/emptyPlaceholder';
import { showModal } from '@/utils/message';
import { getDepartmentAll } from '@/api/config';
import { getAllPost } from '@/api/user';
import { EventBus } from '@/utils/eventBus';
import { mapState } from 'vuex';
export default {
  name: 'PermissionsSetting',
  components: {
    SectionTitle,
    SelectWithoutHttp,
    selectWithUserLoad,
    CascaderSelect,
    EmptyPlaceholder,
    DiversAuditorDialog
  },
  props: {
    permissionFields: {
      type: Array,
      default: () => []
    }
  },
  data() {
    return {
      orders: [],
      curSelectedRows: [],
      orderPrivateId: 1,
      curHandleRow: null,
      errorCell: [],
      deptTreeList: [], // 部门
      readDeptTreeList: [], // 可读部门数据范围
      deptPostList: [], // 职位
      platDeptList: [] // 平铺的部门
    };
  },
  computed: {
    ...mapState({
      'userInfo': state => state.user.userInfo,
      'roleGroupList': state => state.formMake.roleGroups
    }),
    readPermissionList() {
      return [
        { label: '可读', value: 1 },
        { label: '子级部门可读', value: 2 },
        { label: '当前部门可读', value: 4 },
        { label: '顶级部门可读', value: 3 },
        { label: '全部可读', value: 5 }
      ];
    },
    operatePermissionList() {
      return [
        { label: '新建', value: 1 },
        { label: '全部删除', value: 2 },
        { label: '设计表单', value: 3 },
        { label: '批量导出', value: 4 },
        { label: '高级撤回', value: 5 },
        { label: '转交权限', value: 6 },
        { label: '权限设置', value: 7 },
        { label: '删除评论', value: 8 },
        { label: '修改记录查看', value: 9 },
        { label: '数据同步', value: 10 },
        { label: '抄送', value: 11 }
      ];
    }
  },
  watch: {
    orders: {
      handler(list) {
        this.setFieldPermissionsToStore(list);
        this.$emit('statusCheck');
      },
      immediate: true,
      deep: true
    }
  },
  created() {
    this.queryDeptTreeList();
    this.setEventBus();
  },
  methods: {
    changeValue(val, row, index) {
      if (row.selectAllDept && val.includes(-1) && val.length !== this.platDeptList.length) {
        // 已选择所有部门,取消勾选某个部门,需要将所有部门勾选状态取消
        row.deptList = row.deptList.filter(item => {
          if (item !== -1) {
            return item;
          }
        });
        row.selectAllDept = false;
      } else if (val.includes(-1) && !row.selectAllDept) {
        // 勾选所有部门时,需要将所有部门勾上
        row.selectAllDept = true;
        row.deptList = this.platDeptList;
      } else if (row.selectAllDept) {
        // 取消勾选所有部门,需要取消所有勾选
        row.selectAllDept = false;
        row.deptList = [];
      }
    },
    setEventBus() {
      EventBus.$on('formOptionsChange', configObj => {
        // 如果 isKeyNotChange 为true，说明是从 “子表单”移出到“中部/栅格” 或从 “中部/栅格”移出到“子表单”
        if (['remove', 'subtable-remove'].includes(configObj.type) && !configObj.isKeyNotChange) {
          this.resetFieldPermissions(configObj);
        }
      });
    },
    queryDeptTreeList() {
      getDepartmentAll().then(res => {
        this.deptTreeList = res && res.data || [];
        this.readDeptTreeList = _.cloneDeep(this.deptTreeList);
        // this.deptTreeList.splice(0, 0, { id: -1, name: '所有部门全选' });
        this.deptTreeList.push({ id: -1, name: '所有部门全选' });
        this.forEachDept(this.deptTreeList, this.platDeptList);
        this.platDeptList = Array.from(new Set(this.platDeptList)); // 去重
      }).catch(() => false);
    },
    forEachDept(data, arr = []) {
      for (let i = 0; i < data.length; i++) {
        if (data[i].children) {
          this.forEachDept(data[i].children, arr);
        }
        arr.push(data[i].id);
      }
    },
    queryAllPost() {
      const that = this;
      return function(params) {
        return new Promise((resolve, reject) => {
          if (params.userName) params.name = params.userName;
          const postDataCache = that.$store.getters.postList;
          if (params.page === 1 && !params.name && postDataCache && postDataCache.data.items) {
            resolve(postDataCache);
            return;
          }
          getAllPost(params).then(res => {
            if (res.code === 200) {
              res.data.items = res.data.items.map(post => {
                return { id: post, name: post };
              });
              if (!params.name && params.page === 1) that.$store.commit('SET_POSTLIST', res);
            }
            resolve(res);
          }).catch(err => {
            reject(err);
          });
        });
      };
    },
    onSelectChange(list) {
      this.curSelectedRows = list;
    },
    createNewRow() {
      this.orders.push({ orderPrivateId: ++this.orderPrivateId });
    },
    handleDelete(data, index) {
      showModal('是否确定删除?').then(() => {
        this.orders.splice(index, 1);
      });
    },
    handleCopy(rowData) {
      const copyData = _.cloneDeep(rowData);
      copyData.orderPrivateId = ++this.orderPrivateId;
      this.orders.push(copyData);
    },
    handleRowsDel() {
      showModal('确认删除已选中的数据吗？').then(_ => {
        while (this.curSelectedRows.length) {
          const curRow = this.curSelectedRows.pop();
          for (let index = this.orders.length - 1; index >= 0; index--) {
            if (this.orders[index].orderPrivateId === curRow.orderPrivateId) {
              this.orders.splice(index, 1);
            }
          }
        }
      });
    },
    handleChangeVal(data) {
      data && (this.errorCell = []);
    },
    hasMembers(rowData) {
      return rowData['members'] && rowData['members'].length;
    },
    userSelectDialogShow(index) {
      if (this.orders[index].isSelectAll) return;
      this.curHandleRow = index;
      const members = this.orders[this.curHandleRow].members || [];
      this.$refs['auditorDialog'].initSenderData(members, '添加自定义人员', Infinity);
      this.$refs['auditorDialog'].dialogVisible = true;
    },
    userSelectedCallback(data) {
      this.$set(this.orders[this.curHandleRow], 'members', data.selectUser);
    },
    handleSelectAll(val, index) {
      this.$set(this.orders[index], 'members', '');
      this.$set(this.orders[index], 'deptList', '');
      this.$set(this.orders[index], 'postList', '');
      this.$set(this.orders[index], 'roleGroup', '');
    },
    validate() {
      return !!this.orders.filter(item => !item.name).map(item => `name${item.orderPrivateId}`).length;
    },
    validateForm() {
      return new Promise((resolve, reject) => {
        this.errorCell = this.orders.filter(item => !item.name).map(item => `name${item.orderPrivateId}`);
        if (this.errorCell.length) {
          reject('请完善高级设置-权限设置信息');
        } else {
          const sameName = [];
          const nameMap = new Map();
          this.orders.forEach(item => {
            nameMap.has(item.name) ? sameName.push(item.name) : nameMap.set(item.name, true);
          });
          sameName.length ? reject(`高级设置-权限设置存在相同的权限名称：${sameName.join('、')}`) : resolve(true);
        }
      });
    },
    arrayToVal(list, childKey) {
      if (Array.isArray(list) && list.length) {
        return childKey ? list.map(item => item[childKey]).join() : list.join();
      }
      return '';
    },
    // 保存当前用户所有可读字段权限的判断结果
    setFieldPermissionsToStore(list) {
      const allFieldPermissions = [];
      if (Array.isArray(list) && list.length) {
        list.forEach(item => {
          const hasFieldPermission = this.getRowFieldPermission(item);
          hasFieldPermission && allFieldPermissions.push(...item.fieldPermissions);
        });
      }
      this.$store.dispatch('setFieldPermissions', [...new Set(allFieldPermissions)]);
    },
    // 判断字段是否对当前用户不可读
    getRowFieldPermission(data) {
      if (!Array.isArray(data.fieldPermissions) || !data.fieldPermissions.length) return false;
      if (data.isSelectAll) return true;
      let result = false;
      if (Array.isArray(data.members) && data.members.length) {
        result = data.members.some(member => member.id === this.userInfo.id);
      }
      if (!result && Array.isArray(this.userInfo.currentDeptIds) && Array.isArray(data.deptList)) {
        result = data.deptList.some(deptId => this.userInfo.currentDeptIds.includes(Number(deptId)));
      }
      if (!result && Array.isArray(data.postList) && data.postList.length) {
        result = data.postList.some(post => post === this.userInfo.post);
      }
      if (!result && Array.isArray(data.roleGroup) && data.roleGroup.length) {
        result = data.roleGroup.some(roleId => this.userInfo.roleGroupIds.includes(Number(roleId)));
      }
      return result;
    },
    // 表单设计删除字段后，已关联的可读组件字段要同步删除
    resetFieldPermissions(configObj) {
      this.orders.forEach(item => {
        if (Array.isArray(item.fieldPermissions) && item.fieldPermissions.length) {
          const allKeys = this.getAllRemoveKeys(configObj);
          const newFieldPermissions = item.fieldPermissions.filter(key => !allKeys.includes(key));
          this.$set(item, 'fieldPermissions', newFieldPermissions);
        }
      });
    },
    // 将子表单内部的字段一并删除
    getAllRemoveKeys(configObj) {
      const { type, key } = configObj.data;
      if (type === 'subform') {
        const subform = configObj.data.subform || [];
        const subformKeys = subform.map(item => item.key);
        return [key, ...subformKeys];
      } else if (type === 'grid') {
        const keys = [];
        configObj.data.columns.forEach(column => {
          column.list.forEach(item => {
            keys.push(item.key);
          });
        });
        return keys;
      } else {
        return [key];
      }
    },
    getData() {
      return this.orders.map(item => {
        return {
          ...item,
          isSelectAll: !!item.isSelectAll,
          members: item.members || [],
          deptList: this.arrayToVal(item.deptList),
          deptScope: this.arrayToVal(item.deptScope),
          postList: this.arrayToVal(item.postList),
          readPermissions: this.arrayToVal(item.readPermissions),
          roleGroup: this.arrayToVal(item.roleGroup),
          operatePermissions: this.arrayToVal(item.operatePermissions),
          fieldPermissions: this.arrayToVal(item.fieldPermissions)
        };
      });
    },
    setData(list) {
      if (Array.isArray(list) && list.length) {
        this.orders = list.map(item => {
          return {
            ...item,
            deptList: item.deptList && item.deptList.split(',').map(val => Number(val)),
            deptScope: item.deptScope && item.deptScope.split(',').map(val => Number(val)),
            postList: item.postList && item.postList.split(','),
            selectedPostList: item.postList && item.postList.split(',').map(post => { return { id: post, name: post }; }),
            readPermissions: item.readPermissions && item.readPermissions.split(',').map(val => Number(val)),
            roleGroup: item.roleGroup && item.roleGroup.split(',').map(val => Number(val)),
            operatePermissions: item.operatePermissions && item.operatePermissions.split(',').map(val => Number(val)),
            fieldPermissions: item.fieldPermissions && item.fieldPermissions.split(','),
            orderPrivateId: ++this.orderPrivateId
          };
        });
      }
    }
  }
};
</script>

<style scoped lang="scss">
.event-setting-container {
  .title-tip {
    font-size: 14px;
    color: #999;
    font-weight: normal;
    margin-left: 6px;
  }
  .border-left {
    position: relative;
    padding-left:6px;
    margin-left: 6px;
    &::before {
      content: '';
      position: absolute;
      left: 0;
      top: 50%;
      margin-top: -7px;
      width: 1px;
      background: #ddd;
      height: 14px;
    }
  }
  .options-btn-group {
    position: absolute;
    right: 0;
    ::v-deep .el-button {
      padding-left: 12px;
      padding-right: 12px;
    }
  }
  .dept-select-box {
    ::v-deep .el-input__inner::-webkit-input-placeholder {
      color: #c0c4cc;
    }
  }
  .post-selector {
    ::v-deep .el-select__tags-text {
      max-width: 5em;
    }
    ::v-deep input:disabled {
      cursor: not-allowed !important;
    }
  }
  & ::v-deep {
    .filterableSelect {
      width: 100%;
    }
    .el-checkbox__label {
      font-size: 12px;
      padding-left: 4px;
    }
    .el-checkbox {
      color: #333;
    }
    .el-input__inner {
      height: 48px !important;
    }
    .dept-select-container {
      width: 100%;
    }
    .cascader-tags .el-tag {
      max-width: 70px !important;
      > span {
        max-width: 70px !important;
      }
    }
    .el-table {
      thead {
        th.el-table__cell {
          background-color: #F9F9F9 !important;
        }
      }
      tbody {
        .el-table__row {
          &:last-child {
            td {
              border-bottom: 1px solid #EBEEF5;
            }
          }
        }
        .el-icon-arrow-down:before {
          color: #333 !important;
          font-size: 14px !important;
        }
      }
      .el-select {
        width: 100%;
      }
      .el-table__body td {
        background-color: #fff !important;
      }
      .el-select__caret {
        color: #333;
      }
      .el-table__row {
        tr {
          td:last-child {
            height: 48px;
          }
        }
        td {
          padding: 0;
          height: 48px;
        }
        .cell {
          padding: 0;
          .el-input__inner {
            border-radius: 0;
            width: 100%;
            height: 48px;
            text-overflow: ellipsis;
            padding-right: 30px;
            border-color: transparent;
          }
        }
      }
      .el-table__empty-text {
        width: 100%;
      }
    }
  }
  .members-box {
    display: flex;
    align-items: center;
    height: 48px;
    cursor: pointer;
    line-height: 48px;
    .member-checked {
      color: #406eff;
      margin-left: 10px;
    }
    .operate-input {
      ::v-deep .el-input__inner {
        cursor: pointer;
      }
    }
  }
  .isError {
    &::v-deep {
      .el-input__inner {
        border-color: red !important;
      }
      .attachment-container {
        border:1px solid red;
      }
    }
  }
}

</style>
<style lang="scss">
.fixed-dept {
  .el-cascader-panel {
    .el-cascader-node:last-child {
      position: sticky;
      bottom: 0;
      background-color: #fff;
      z-index: 333;
    }
    .el-cascader-menu__list {
      padding-bottom: 0;
    }
  }
}
</style>
